/**
 * 底部Sheet组件
 * Story 5: Task 4 - 底部Sheet组件
 */

import React, { useEffect } from 'react'
import { useSpring, animated } from '@react-spring/web'
import { useDrag } from '@use-gesture/react'
import { useHapticFeedback } from '../../../hooks/gestures'
import './style.css'

export interface BottomSheetProps {
  open: boolean
  onClose: () => void
  children: React.ReactNode
  snapPoints?: number[] // 吸附点，0-1之间的比例
  title?: string
  showHandle?: boolean
}

/**
 * 底部Sheet组件
 * 支持拖拽关闭、吸附点、触觉反馈
 */
export const BottomSheet: React.FC<BottomSheetProps> = ({
  open,
  onClose,
  children,
  snapPoints = [0.6, 1],
  title,
  showHandle = true,
}) => {
  const { trigger: triggerHaptic } = useHapticFeedback()
  const windowHeight = window.innerHeight

  const [{ y }, api] = useSpring(() => ({
    y: windowHeight,
    config: { tension: 300, friction: 30 },
  }))

  // 找到最近的吸附点
  const findNearestSnapPoint = (currentY: number): number => {
    const currentRatio = 1 - currentY / windowHeight
    let nearest = snapPoints[0]
    let minDiff = Math.abs(currentRatio - nearest)

    snapPoints.forEach((point) => {
      const diff = Math.abs(currentRatio - point)
      if (diff < minDiff) {
        minDiff = diff
        nearest = point
      }
    })

    return windowHeight * (1 - nearest)
  }

  // 拖拽绑定
  const bind = useDrag(
    ({ down, movement: [, my], velocity: [, vy], direction: [, dy], event }) => {
      event?.preventDefault()

      if (!open) return

      // 计算当前Y位置（初始位置 + 拖拽距离）
      const initialY = windowHeight * (1 - snapPoints[0])
      let currentY = initialY + my

      // 限制最小值
      const minY = windowHeight * (1 - Math.max(...snapPoints))
      currentY = Math.max(minY, currentY)

      if (down) {
        // 拖拽中
        api.start({ y: currentY, immediate: true })
      } else {
        // 释放时判断
        const threshold = windowHeight * 0.3
        const shouldClose = currentY > threshold && (vy > 0.5 || dy > 0)

        if (shouldClose) {
          // 关闭
          api.start({ y: windowHeight })
          triggerHaptic('light')
          setTimeout(onClose, 200)
        } else {
          // 吸附到最近的点
          const nearestY = findNearestSnapPoint(currentY)
          api.start({ y: nearestY })
          triggerHaptic('light')
        }
      }
    },
    {
      from: () => [0, y.get()],
      filterTaps: true,
      pointer: { touch: true },
    }
  )

  // 打开/关闭动画
  useEffect(() => {
    if (open) {
      const targetY = windowHeight * (1 - snapPoints[0])
      api.start({ y: targetY })
      triggerHaptic('medium')
    } else {
      api.start({ y: windowHeight })
    }
  }, [open, api, snapPoints, windowHeight, triggerHaptic])

  // 点击遮罩关闭
  const handleOverlayClick = () => {
    api.start({ y: windowHeight })
    triggerHaptic('light')
    setTimeout(onClose, 200)
  }

  // 阻止Sheet内容点击事件冒泡
  const handleSheetClick = (e: React.MouseEvent) => {
    e.stopPropagation()
  }

  return (
    <>
      {/* 遮罩层 */}
      <animated.div
        className="bottom-sheet-overlay"
        style={{
          opacity: y.to([windowHeight, windowHeight * 0.4], [0, 0.5]),
          pointerEvents: open ? 'auto' : 'none',
        }}
        onClick={handleOverlayClick}
      />

      {/* Sheet内容 */}
      <animated.div
        className="bottom-sheet"
        style={{
          y,
          touchAction: 'none',
        }}
        onClick={handleSheetClick}
        {...bind()}
      >
        {/* 拖拽把手 */}
        {showHandle && (
          <div className="bottom-sheet-handle-container">
            <div className="bottom-sheet-handle" />
          </div>
        )}

        {/* 标题 */}
        {title && (
          <div className="bottom-sheet-header">
            <h3 className="bottom-sheet-title">{title}</h3>
          </div>
        )}

        {/* 内容区域 */}
        <div className="bottom-sheet-content">{children}</div>
      </animated.div>
    </>
  )
}
